home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Magazine / Online / OpenURL / Developer / Source / library_api.c < prev    next >
C/C++ Source or Header  |  1999-09-26  |  11KB  |  444 lines

  1. /* 
  2. ** openurl.library - universal URL display and browser launcher library
  3. ** Written by Troels Walsted Hansen <troels@thule.no>
  4. ** Placed in the public domain.
  5. **
  6. ** Main module for the library with all API functions.
  7. */
  8.  
  9. #include "library_common.h"
  10. #include "library_api.h"
  11. #include "library_prefs.h"
  12. #include "library_util.h"
  13. #include "handler.h"
  14.  
  15. /**************************************************************************
  16. *
  17. * Global variables.
  18. *
  19. */
  20.  
  21. struct DosLibrary *DOSBase = NULL;
  22. struct Library *UtilityBase = NULL;
  23. struct IntuitionBase *IntuitionBase = NULL;
  24. struct Library *IFFParseBase = NULL;
  25. struct RxsLib *RexxSysBase = NULL;
  26. struct URL_Prefs *Prefs = NULL;
  27. struct SignalSemaphore PrefsSemaphore, HandlerSemaphore;
  28.  
  29. struct Process *HandlerProcess = NULL;
  30. struct MsgPort *HandlerMsgPort;
  31.  
  32. /**************************************************************************
  33. *
  34. * SAS/C library functions.
  35. *
  36. */
  37.  
  38. LIB int __UserLibInit(REG(a6) struct Library *OpenURLBase)
  39. {
  40.     int retval = 1;
  41.     BPTR seglist;
  42.     struct MsgPort *mp = NULL;
  43.     struct HandlerMsg hm = {0};
  44.  
  45.     /* run time initialized globals */
  46.  
  47.     SysBase = *(struct ExecBase **)4;
  48.     InitSemaphore(&PrefsSemaphore);
  49.     InitSemaphore(&HandlerSemaphore);
  50.  
  51.     /* open libraries */
  52.  
  53.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36)))
  54.         goto done;
  55.  
  56.     if(!(UtilityBase = OpenLibrary("utility.library", 36)))
  57.         goto done;
  58.  
  59.     if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36)))
  60.         goto done;
  61.  
  62.     if(!(IFFParseBase = OpenLibrary("iffparse.library", 36)))
  63.         goto done;
  64.  
  65.     if(!(RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", 33)))
  66.         goto done;
  67.  
  68.     /* load prefs */
  69.  
  70.     if(!LoadPrefs(PREFS_NAME_USE) && !(Prefs = LIB_URL_GetDefaultPrefs()))
  71.         goto done;
  72.  
  73.     /* load and launch handler */
  74.  
  75.     if(!(mp = CreateMsgPort()))
  76.         goto done;
  77.  
  78.     if(!(seglist = LoadSeg("L:OpenURL-Handler")))
  79.     {
  80.         struct EasyStruct es;
  81.         es.es_StructSize   = sizeof(struct EasyStruct);
  82.         es.es_Flags        = 0;
  83.         es.es_Title        = "OpenURL Error";
  84.         es.es_TextFormat   = "openurl.library was unable to load\n"
  85.                            "L:OpenURL-Handler into memory.\n"
  86.                            "Please reinstall.";
  87.         es.es_GadgetFormat = "Ok";
  88.         EasyRequestArgs(NULL, &es, NULL, NULL);
  89.         goto done;
  90.     }
  91.  
  92.     HandlerProcess = CreateNewProcTags(NP_Seglist,     seglist,
  93.                                        NP_Name,        "OpenURL ARexx Handler",
  94.                                        NP_Priority,    0,
  95.                                        NP_StackSize,   4096,
  96.                                        NP_Input,       NULL,
  97.                                        NP_Output,      NULL,
  98.                                        NP_CloseInput,  FALSE,
  99.                                        NP_CloseOutput, FALSE,
  100.                                        NP_CurrentDir,  NULL,
  101.                                        NP_HomeDir,     NULL,
  102.                                        NP_CopyVars,    FALSE,
  103.                                        TAG_DONE);
  104.  
  105.     if(!HandlerProcess)
  106.     {
  107.         UnLoadSeg(seglist);
  108.         goto done;
  109.     }
  110.  
  111.     /* use a startup msg to synchronize with the handler */
  112.  
  113.     hm.hm_Msg.mn_ReplyPort = mp;
  114.     hm.hm_Msg.mn_Length    = sizeof(struct HandlerMsg);
  115.     hm.hm_Type             = HMT_STARTUP;
  116.     hm.hm_Semaphore        = &HandlerSemaphore;
  117.  
  118.     PutMsg(&(HandlerProcess->pr_MsgPort), (struct Message *)&hm);
  119.     WaitPort(mp);
  120.     GetMsg(mp);
  121.  
  122.     /* check that handler initialized its resources correctly */
  123.  
  124.     if(!hm.hm_Success)
  125.     {
  126.         HandlerProcess = NULL;
  127.         goto done;
  128.     }
  129.  
  130.     HandlerMsgPort = hm.hm_MsgPort;
  131.     retval         = 0;
  132.  
  133. done:
  134.     if(mp) DeleteMsgPort(mp);
  135.     if(retval) __UserLibCleanup(OpenURLBase);
  136.     return(retval);
  137. }
  138.  
  139. /**************************************************************************/
  140.  
  141. LIB void __UserLibCleanup(REG(a6) struct Library *OpenURLBase)
  142. {
  143.     /* shutdown handler process */
  144.  
  145.     if(!AttemptSemaphore(&HandlerSemaphore))
  146.     {
  147.         /* process is still alive, and holding semaphore.
  148.            signal it to terminate */
  149.  
  150.         Signal((struct Task *)HandlerProcess, SIGBREAKF_CTRL_C);
  151.     }
  152.     else ReleaseSemaphore(&HandlerSemaphore);
  153.  
  154.     /* free other resources */
  155.  
  156.     if(Prefs) LIB_URL_FreePrefs(Prefs);
  157.     CloseLibrary((struct Library *)RexxSysBase);
  158.     CloseLibrary(IFFParseBase);
  159.     CloseLibrary((struct Library *)IntuitionBase);
  160.     CloseLibrary(UtilityBase);
  161.     CloseLibrary((struct Library *)DOSBase);
  162. }
  163.  
  164. /**************************************************************************
  165. *
  166. * Library functions available through API.
  167. *
  168. */
  169.  
  170. LIB BOOL LIB_URL_OpenA(REG(a0) STRPTR url, REG(a1) struct TagItem *tags)
  171. {
  172.     BOOL retval = FALSE;
  173.     struct List portlist;
  174.     struct MsgPort *mp;
  175.     STRPTR fullurl = NULL;
  176.     BOOL Show, ToFront, NewWindow, Launch;
  177.     BOOL http_prepend = FALSE;
  178.  
  179.     /* some initialization */
  180.  
  181.     NewList(&portlist);
  182.     ObtainSemaphore(&PrefsSemaphore);
  183.  
  184.     if(!(mp = CreateMsgPort()))
  185.         goto done;
  186.  
  187.     /* parse the arguments */
  188.  
  189.     Show      = GetTagData(URL_Show,         Prefs->up_DefShow,         tags);
  190.     ToFront   = GetTagData(URL_BringToFront, Prefs->up_DefBringToFront, tags);
  191.     NewWindow = GetTagData(URL_NewWindow,    Prefs->up_DefNewWindow,    tags);
  192.     Launch    = GetTagData(URL_Launch,       Prefs->up_DefLaunch,       tags);
  193.  
  194.     /* make a copy of the global list of named ports */
  195.  
  196.     Forbid();
  197.     retval = CopyList(&portlist, &SysBase->PortList, sizeof(struct Node));
  198.     Permit();
  199.  
  200.     if(!retval) goto done;
  201.  
  202.     /* prepend "http://" if URL has no method */
  203.  
  204.     if(Prefs->up_Flags & UPF_PREPENDHTTP)
  205.     {
  206.         STRPTR colon;
  207.  
  208.         colon = strchr(url, ':');
  209.  
  210.         if(!colon)
  211.             http_prepend = TRUE;
  212.         else
  213.         {
  214.             STRPTR p;
  215.  
  216.             for(p = url; p < colon; p++)
  217.             {
  218.                 if(!isalnum(*p) && (*p != '+') && (*p != '-'))
  219.                 {
  220.                     http_prepend = TRUE;
  221.                     break;
  222.                 }
  223.             }
  224.         }
  225.     }
  226.  
  227.     if(http_prepend)
  228.     {
  229.         if(!(fullurl = AllocVec(strlen(url) + 8, MEMF_PUBLIC)))
  230.             goto done;
  231.  
  232.         SPrintf(fullurl, "http://%s", url);
  233.     }
  234.     else fullurl = url;
  235.  
  236.     /* mailto: or generic URL? */
  237.  
  238.     if((Prefs->up_Flags & UPF_DOMAILTO) && !strncmp(url, "mailto:", 7))
  239.         retval = SendToMailer(fullurl, &portlist, mp, Show, ToFront, Launch);
  240.     else
  241.         retval = SendToBrowser(fullurl, &portlist, mp, Show, ToFront, NewWindow, Launch);
  242.  
  243. done:
  244.     ReleaseSemaphore(&PrefsSemaphore);
  245.     FreeList(&portlist, sizeof(struct Node));
  246.     if(mp) DeleteMsgPort(mp);
  247.     if(http_prepend && fullurl) FreeVec(fullurl);
  248.     return(retval);
  249. }
  250.  
  251. /**************************************************************************/
  252.  
  253. LIB struct URL_Prefs *LIB_URL_GetPrefs(VOID)
  254. {
  255.     struct URL_Prefs *p;
  256.  
  257.     /* make a copy of the prefs structure and return that */
  258.  
  259.     ObtainSemaphoreShared(&PrefsSemaphore);
  260.     p = CopyPrefs(Prefs);
  261.     ReleaseSemaphore(&PrefsSemaphore);
  262.     return(p);
  263. }
  264.  
  265. /**************************************************************************/
  266.  
  267. LIB VOID LIB_URL_FreePrefs(REG(a0) struct URL_Prefs *up)
  268. {
  269.     /* free a prefs structure */
  270.     FreeList((struct List *)&up->up_BrowserList, sizeof(struct URL_BrowserNode));
  271.     FreeList((struct List *)&up->up_MailerList, sizeof(struct URL_MailerNode));
  272.     FreeMem(up, sizeof(struct URL_Prefs));
  273. }
  274.  
  275. /**************************************************************************/
  276.  
  277. LIB BOOL LIB_URL_SetPrefs(REG(a0) struct URL_Prefs *p, REG(d0) BOOL permanent)
  278. {
  279.     BOOL retval = FALSE;
  280.     struct URL_Prefs *new_p;
  281.  
  282.     ObtainSemaphore(&PrefsSemaphore);
  283.  
  284.     /* copy prefs structure */
  285.  
  286.     if(!(new_p = CopyPrefs(p)))
  287.         goto done;
  288.  
  289.     if(new_p->up_Version > PREFS_VERSION)
  290.         goto done;
  291.  
  292.     if(new_p->up_Version < 2)
  293.         SetDefaultPrefsV2(new_p);
  294.  
  295.     if(new_p->up_Version == 2)
  296.         ConvertPrefsV2toV3(Prefs);
  297.  
  298.     if(new_p->up_Version < 3)
  299.         SetDefaultPrefsV3(new_p);
  300.  
  301.     new_p->up_Version = PREFS_VERSION;
  302.     new_p->up_Flags &= ~UPF_ISDEFAULTS;
  303.  
  304.     LIB_URL_FreePrefs(Prefs);
  305.     Prefs = new_p;
  306.  
  307.     /* and save it to disk */
  308.  
  309.     if(!SavePrefs(PREFS_NAME_USE, Prefs)) goto done;
  310.     if(permanent && !SavePrefs(PREFS_NAME_SAVE, Prefs))
  311.         goto done;
  312.  
  313.     retval = TRUE;
  314. done:
  315.     ReleaseSemaphore(&PrefsSemaphore);
  316.     return(retval);
  317. }
  318.  
  319.  
  320. /**************************************************************************/
  321.  
  322. LIB struct URL_Prefs *LIB_URL_GetDefaultPrefs(VOID)
  323. {
  324.     struct URL_Prefs *p;
  325.  
  326.     if(!(p = AllocMem(sizeof(struct URL_Prefs), MEMF_CLEAR)))
  327.         return(NULL);
  328.  
  329.     p->up_Version = PREFS_VERSION;
  330.     p->up_Flags |= UPF_ISDEFAULTS;
  331.  
  332.     if(!SetDefaultPrefsV1(p))
  333.     {
  334.         LIB_URL_FreePrefs(p);
  335.         return(NULL);
  336.     }
  337.  
  338.     SetDefaultPrefsV2(p);
  339.  
  340.     if(!SetDefaultPrefsV3(p))
  341.     {
  342.         LIB_URL_FreePrefs(p);
  343.         return(NULL);
  344.     }
  345.  
  346.     return(p);
  347. }
  348.  
  349. /**************************************************************************/
  350.  
  351. LIB BOOL LIB_URL_LaunchPrefsApp(VOID)
  352. {
  353.     char path[256];
  354.  
  355.     if(GetVar("OpenURL_Prefs_Path", path, sizeof(path), 0) == -1)
  356.         strcpy(path, "SYS:Prefs/OpenURL");
  357.  
  358.     if(SystemTags(path,
  359.                   SYS_Asynch, TRUE,
  360.                   SYS_Input,  Open("NIL:", MODE_NEWFILE),
  361.                   SYS_Output, NULL,
  362.                   TAG_END) == -1)
  363.         return(FALSE);
  364.     else
  365.         return(TRUE);
  366. }
  367.  
  368. /**************************************************************************/
  369.  
  370. ASM ULONG a0hack(REG(d0) ULONG return1, REG(a0) UBYTE *return2)
  371. {
  372.     /* lame hack to return an argstring in A0 as arexx expects */
  373.     return(return1);
  374. }
  375.  
  376. LIB ULONG LIB_DoFunction(REG(a0) struct RexxMsg *rxmsg)
  377. {
  378.     UBYTE *argstr;
  379.     STRPTR resstr;
  380.  
  381.     /* check validity of rexx msg */
  382.  
  383.     if(!rxmsg || !IsRexxMsg(rxmsg) || !(rxmsg->rm_Action & RXFUNC) ||
  384.        !rxmsg->rm_Args[0])
  385.     {
  386.         return(ERR10_010); /*  invalid message packet      */
  387.     }
  388.  
  389.     /* check that we recognise the command */
  390.  
  391.     if(!stricmp(rxmsg->rm_Args[0], "OPENURL"))
  392.     {
  393.         struct TagItem tags[MAXRMARG + 1];
  394.         STRPTR url = NULL;
  395.         int i, j;
  396.  
  397.         /* parse the arguments (ReadArgs would be overkill for this) */
  398.  
  399.         for(i = 1, j = 0; rxmsg->rm_Args[i] && j < MAXRMARG; i++)
  400.         {
  401.             Tag tag;
  402.  
  403.             if(!stricmp(rxmsg->rm_Args[i], "SHOW") || !stricmp(rxmsg->rm_Args[i], "NOSHOW"))
  404.                 tag = URL_Show;
  405.             else if(!stricmp(rxmsg->rm_Args[i], "TOFRONT") || !stricmp(rxmsg->rm_Args[i], "NOTOFRONT"))
  406.                 tag  = URL_BringToFront;
  407.             else if(!stricmp(rxmsg->rm_Args[i], "NEWWIN") || !stricmp(rxmsg->rm_Args[i], "NONEWWIN"))
  408.                 tag = URL_NewWindow;
  409.             else if(!stricmp(rxmsg->rm_Args[i], "LAUNCH") || !stricmp(rxmsg->rm_Args[i], "NOLAUNCH"))
  410.                 tag  = URL_Launch;
  411.             else
  412.             {
  413.                 url = rxmsg->rm_Args[i];
  414.                 continue;
  415.             }
  416.  
  417.             tags[j].ti_Tag  = tag;
  418.             tags[j].ti_Data = strnicmp(rxmsg->rm_Args[i], "NO", 2);
  419.             j++;
  420.         }
  421.  
  422.         tags[j].ti_Tag = TAG_END;
  423.  
  424.         if(url && LIB_URL_OpenA(url, tags))
  425.             resstr = "1";
  426.         else
  427.             resstr = "0";
  428.     }
  429.     else if(!stricmp(rxmsg->rm_Args[0], "OPENURLPREFS"))
  430.     {
  431.         if(LIB_URL_LaunchPrefsApp())
  432.             resstr = "1";
  433.         else
  434.             resstr = "0";
  435.     }
  436.     else
  437.         return(ERR10_001); /*  program not found           */
  438.  
  439.     if(!(argstr = CreateArgstring(resstr, 1)))
  440.         return(ERR10_003); /*  no memory available           */
  441.  
  442.     return(a0hack(0, argstr));
  443. }
  444.